package com.ctgu.computer.service.impl;

import com.ctgu.computer.common.UserLocalTread;
import com.ctgu.computer.domain.dto.CallCommentDTO;
import com.ctgu.computer.domain.dto.CommentDTO;
import com.ctgu.computer.domain.dto.FirstPageCommentDTO;
import com.ctgu.computer.domain.dto.SecondCommentDTO;
import com.ctgu.computer.domain.po.*;
import com.ctgu.computer.domain.result.PageResult;
import com.ctgu.computer.domain.vo.FirstPageCommentVO;
import com.ctgu.computer.domain.vo.SecondCommentVO;
import com.ctgu.computer.mapper.CommentMapper;
import com.ctgu.computer.mapper.TopicMapper;
import com.ctgu.computer.mapper.UserMapper;
import com.ctgu.computer.schedule.ScheduleTask;
import com.ctgu.computer.service.CommentService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.opentracing.propagation.TextMap;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class CommentServiceImpl implements CommentService {

    private final CommentMapper commentMapper;
    private final UserMapper userMapper;
    private final TopicMapper topicMapper;
    @Override
    @Transactional
    public void sendComment(CommentDTO commentDTO) {
        CommentInfo commentInfo = new CommentInfo();
        commentInfo.setCommentContent(commentDTO.getCommentContent());
        commentMapper.insert(commentInfo);
        CommentTextSenderInfo commentTextSenderInfo = CommentTextSenderInfo.builder()
                .callCommentId(commentDTO.getCallCommentId())
                .textId(commentDTO.getTextId())
                .senderId(UserLocalTread.getUserId() != null ? UserLocalTread.getUserId() : UserLocalTread.getAdminId())
                .commentId(commentInfo.getCommentId())
                .build();
        commentMapper.insertCommentTextSenderInfo(commentTextSenderInfo);
        TextInfo textInfo = topicMapper.selectById(commentDTO.getTextId());
        topicMapper.update(TextInfo.builder()
                        .commentCount(textInfo.getCommentCount()+1)
                        .textId(textInfo.getTextId())
                .build());
    }

    @Override
    public PageResult pageFirstComment(FirstPageCommentDTO firstPageCommentDTO) {
        PageHelper.startPage(firstPageCommentDTO.getPageIndex(),firstPageCommentDTO.getPageSize());
        Page<CommentTextSenderInfo> list = commentMapper.firstPageCommentPage(firstPageCommentDTO);
        // 获取每条评论的id
        List<Integer> commentIds = list.getResult().
                stream().map(CommentTextSenderInfo::getCommentId).collect(Collectors.toList());
        Map<Integer,CommentInfo> commentInfos = commentMapper.getCommentsByIds(commentIds);
        // 获取当前用户点赞过评论
        List<Integer> goodCommentIds = commentMapper.batchSelect(new UserIdToCommentIds(UserLocalTread.getUserId(),commentIds));
        if(goodCommentIds==null){
            goodCommentIds=new ArrayList<>();
        }
        // 获取每条评论的发送者
        List<Integer> senderIds = list.getResult()
                .stream().map(CommentTextSenderInfo::getSenderId).collect(Collectors.toList());
        Map<Integer,UserInfo> senderInfos = userMapper.selectUserNameByIds(senderIds);
        // 构造VO对象
        List<FirstPageCommentVO> result = new ArrayList<>();
        for (CommentTextSenderInfo commentTextSenderInfo : list) {
            CommentInnerUser commentInnerUser = new CommentInnerUser(
                    senderInfos.get(commentTextSenderInfo.getSenderId()).getUserName(),
                    senderInfos.get(commentTextSenderInfo.getSenderId()).getImage()
            );
            result.add(FirstPageCommentVO.builder()
                            .commentContent(commentInfos.get(commentTextSenderInfo.getCommentId()).getCommentContent())
                            .sender(commentInnerUser)
                            .senderName(senderInfos.get(commentTextSenderInfo.getSenderId()).getUserName())
                            .senderId(commentTextSenderInfo.getSenderId())
                            .createTime(commentInfos.get(commentTextSenderInfo.getCommentId()).getCreateTime())
                            .commentId(commentTextSenderInfo.getCommentId())
                            .goodCount(commentInfos.get(commentTextSenderInfo.getCommentId()).getGoodCount())
                            .isGood(goodCommentIds.contains(commentTextSenderInfo.getCommentId()))
                    .build());
        }
        return new PageResult(list.getTotal(),result);
    }

    @Override
    public PageResult pageSecondComment(SecondCommentDTO secondCommentDTO) {
        //获取当前被回复的评论者用户名
        Integer calledUserId = commentMapper.getCommentTextSender(secondCommentDTO.getCommentId()).getSenderId();
        String calledUserName = userMapper.selectUserInfoById(calledUserId).getUserName();
        PageHelper.startPage(secondCommentDTO.getPageIndex(),secondCommentDTO.getPageSize());
        Page<CommentTextSenderInfo> list = commentMapper.getCommentTextSenderListByCallCommentId(secondCommentDTO.getCommentId());
        // 所有回复评论的id值
        List<Integer> commentIds = list.stream().map(CommentTextSenderInfo::getCommentId).collect(Collectors.toList());
        // 获取所有评论者的id
        List<Integer> senderIds = list.stream().map(CommentTextSenderInfo::getSenderId).collect(Collectors.toList());
        // 相关评论id对应的具体信息
        Map<Integer,CommentInfo> commentInfoMap = commentMapper.getCommentsByIds(commentIds);
        // 对应用户id和用户实体的映射
        Map<Integer,UserInfo> userInfoMap = userMapper.selectUserNameByIds(senderIds);
        // 活动当前用户点赞的评论id
        List<Integer> goodCommentIds = commentMapper.batchSelect(new UserIdToCommentIds(UserLocalTread.getUserId(),commentIds));
        if(goodCommentIds==null){
            goodCommentIds=new ArrayList<>();
        }
        // 构造前端VO对象
        List<SecondCommentVO> result = new ArrayList<>();
        for (CommentTextSenderInfo commentTextSenderInfo : list) {
            CommentInnerUser commentInnerUser = new CommentInnerUser(
                    userInfoMap.get(commentTextSenderInfo.getSenderId()).getUserName(),
                    userInfoMap.get(commentTextSenderInfo.getSenderId()).getImage()
            );
            result.add(SecondCommentVO.builder()
                            .senderId(commentTextSenderInfo.getSenderId())
                            .sender(commentInnerUser)
                            .goodCount(commentInfoMap.get(commentTextSenderInfo.getCommentId()).getGoodCount())
                            .commentId(commentTextSenderInfo.getCommentId())
                            .SenderUserName(userInfoMap.get(commentTextSenderInfo.getSenderId()).getUserName())
                            .calledUserName(calledUserName)
                            .createTime(commentInfoMap.get(commentTextSenderInfo.getCommentId()).getCreateTime())
                            .commentContent(commentInfoMap.get(commentTextSenderInfo.getCommentId()).getCommentContent())
                            .isGood(goodCommentIds.contains(commentTextSenderInfo.getCommentId()))
                    .build());
        }
        return new PageResult(list.getTotal(),result);
    }

    @Override
    @Transactional
    public void callComment(CallCommentDTO callCommentDTO) {
        // 获取对应的评论发表的文章id，用户id
        CommentTextSenderInfo commentTextSenderInfo = commentMapper.getCommentTextSender(callCommentDTO.getCommentId());
        CommentInfo commentInfo = new CommentInfo();
        commentInfo.setCommentContent(callCommentDTO.getCommentContent());
        commentMapper.insert(commentInfo);
        // 构造新的文章，评论，用户，回复用户关系实例
        CommentTextSenderInfo newCommentTextSenderInfo = CommentTextSenderInfo.builder()
                .commentId(commentInfo.getCommentId())
                .callCommentId(callCommentDTO.getCommentId())
                .textId(commentTextSenderInfo.getTextId())
                .senderId(UserLocalTread.getUserId())
                .firstCommentId(commentTextSenderInfo.getFirstCommentId()!=null?commentTextSenderInfo.getFirstCommentId():callCommentDTO.getCommentId())
                .build();
        commentMapper.insertCommentTextSenderInfo(newCommentTextSenderInfo);
        TextInfo textInfo = topicMapper.selectById(commentTextSenderInfo.getTextId());
        topicMapper.update(TextInfo.builder()
                .commentCount(textInfo.getCommentCount()+1)
                .textId(textInfo.getTextId())
                .build());
    }

    @Override
    @Transactional
    public void delete(Integer commentId) {
        CommentTextSenderInfo commentTextSenderInfo = commentMapper.getCommentTextSender(commentId);
        TextInfo textInfo = topicMapper.selectById(commentTextSenderInfo.getTextId());
        commentMapper.deleteCommentTextSender(commentId);
        List<Integer> commentIds = new ArrayList<>();
        commentIds.add(commentId);
        commentMapper.batchDelete(commentIds);
        topicMapper.update(TextInfo.builder()
                .commentCount(textInfo.getCommentCount()-1)
                .textId(textInfo.getTextId())
                .build());
    }

    @Override
    @Transactional
    public void good(Integer commentId) {
        CommentInfo commentInfo = commentMapper.selectById(commentId);
        // 判断是否点过赞
        GoodComment goodComment =commentMapper.selectGood(commentId,UserLocalTread.getUserId());
        if(goodComment==null){
            commentMapper.insertGood(GoodComment.builder()
                    .isGood(true)
                    .gooderId(UserLocalTread.getUserId())
                    .commentId(commentId)
                    .build());
            commentMapper.update(CommentInfo.builder()
                    .commentId(commentId)
                    .goodCount(commentInfo.getGoodCount()+1)
                    .build());
            return;
        }
        if(goodComment.getIsGood()){
            goodComment.setIsGood(false);
            commentMapper.updateGood(goodComment);
            commentMapper.update(CommentInfo.builder()
                            .commentId(commentId)
                            .goodCount(commentInfo.getGoodCount()-1)
                    .build());
        }else{
            goodComment.setIsGood(true);
            commentMapper.updateGood(goodComment);
            commentMapper.update(CommentInfo.builder()
                    .commentId(commentId)
                    .goodCount(commentInfo.getGoodCount()+1)
                    .build());
        }
    }
}
